package org.testis.testdriver.parser;

import org.testis.data.parser.AtofModuleParameterNames;
import org.testis.orm.testbed.refined.DeviceGroupDetailRefined;
import org.testis.orm.testbed.refined.DeviceGroupFactory;
import org.testis.orm.testbed.refined.DeviceGroupRefined;
import org.testis.orm.testbed.refined.DutRefined;
import org.testis.orm.testbed.refined.NetworkAdapterRefined;
import org.testis.orm.testbed.refined.TestPcFactory;
import org.testis.orm.testbed.refined.TestPcRefined;
import org.testis.testdriver.AtofEnumaration;
import org.testis.testdriver.ITestBuilder;
import org.testis.testdriver.TestPlanBuilder;
import org.testis.testdriver.TestPlanGlobalsHashMap;
import org.testis.testdriver.translation.AtofValueTranslateService;
import org.testis.testdriver.translation.UnidentifiedTranslationException;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import org.orm.PersistentException;
import org.testis.orm.refinedclasses.TestDesignTreeNode;
import org.testis.orm.refinedclasses.TestPlanRefined;
import org.testis.orm.refinedclasses.TestStepRefined;
import org.testis.orm.refinedclasses.TestSuiteRefined;
import org.testis.orm.refinedclasses.TestDesignTreeRefined.TestDesignTreeParameters;
import org.testis.utils.middleware.TestDesign;

/**
 *
 * @author barisergun
 */
public class TestDriverTestStepRefinedParsing extends TestDriverAbstractParsingStrategy {

    public TestDriverTestStepRefinedParsing(ITestBuilder builder,
            TestDesignTreeNode currentNode) {
        m_builder = builder;
        m_currentNode = currentNode;

        if (m_currentNode.isClone()) {
            m_cloneString = " [clone]";
        }
    }

    @Override
    public void parseCurrentNode() throws PersistentException {
        String deviceIp = m_currentNode.getReference().getParameterStringValue(TestDesignTreeParameters.DeviceIp.name());
        Integer deviceId = m_currentNode.getReference().getParameterIntValue(TestDesignTreeParameters.DeviceId.name());
        String curBrowserType = m_currentNode.getReference().getParameterStringValue(TestDesignTreeParameters.BrowserType.name());
        Integer curBrowserSpeed = m_currentNode.getReference().getParameterIntValue(TestDesignTreeParameters.BrowserSpeed.name());
        Integer pcId = m_currentNode.getReference().getParameterIntValue(TestDesignTreeParameters.PcId.name());
        Integer delayTime = m_currentNode.getReference().getParameterIntValue(TestDesignTreeParameters.DelayTime.name());
        Integer delayTimeAfterExecute = m_currentNode.getReference().getParameterIntValue(TestDesignTreeParameters.AfterDelayTime.name());
        String storeResultPostfix = m_currentNode.getReference().getParameterStringValue(TestDesignTreeParameters.StoreResultPostfix.name());
        if (storeResultPostfix == null) {
            storeResultPostfix = "";
        }
        Boolean dataArrayAppliestoCase = m_currentNode.getReference().getParameterBooleanValue(TestDesignTreeParameters.DataArrayAppliestoCase.name());
        Boolean asynchCall = m_currentNode.getReference().getParameterBooleanValue(TestDesignTreeParameters.AsynchCall.name());
        Integer noOfRetryOnFail = m_currentNode.getReference().getParameterIntValue(TestDesignTreeParameters.NoOfRetryOnFail.name());
        Boolean critical = m_currentNode.getReference().getParameterBooleanValue(TestDesignTreeParameters.Critical.name());
        Integer timeout = m_currentNode.getReference().getParameterIntValue(TestDesignTreeParameters.Timeout.name());
        Integer nicId = m_currentNode.getReference().getParameterIntValue(TestDesignTreeParameters.NicId.name());
        Byte successPercentage = m_currentNode.getReference().getParameterByteValue(TestDesignTreeParameters.SuccessPercentage.name());
        DutRefined device = null;
        TestPcRefined pc = null;
        if (pcId != null) {
            pc = TestPcFactory.newInstance().getTestPc(pcId);
        }
        if (deviceId != null && pc != null) {
            device = pc.getDut(deviceId);
        }
        NetworkAdapterRefined nicAdapter = null;
        if (nicId != null && pc != null) {
            nicAdapter = pc.getNetworkAdapter(nicId);
        }

        LinkedList<String> condList = getConditionsOfTestPart();



        TestDesignTreeNode parentTestPlan = m_currentNode.getParent();
        while (!(parentTestPlan.getObject() instanceof TestPlanRefined)) {
            parentTestPlan = parentTestPlan.getParent();
            if (parentTestPlan.getObject() instanceof TestSuiteRefined) {
                for (int y = 0; y < parentTestPlan.getChildrenForRun().length;
                        y++) {
                    if (parentTestPlan.getChildrenForRun()[y].getObject() instanceof TestPlanRefined) {
                        parentTestPlan = parentTestPlan.getChildrenForRun()[y];
                        break;
                    }
                }

                break;
            }
        }

        if (!(parentTestPlan.getObject() instanceof TestPlanRefined)) {

            if (m_builder instanceof TestPlanBuilder) {
                ((TestPlanBuilder) m_builder).pushExceptionMessage(
                        "Test Steps always must have a grand"
                        + " parent as Test Plan. This Step is missing a grand parent as TestPlan. "
                        + "Problem Node:"
                        + getCurrentNodePath());
            }

        }

        TestStepRefined testPart =
                (TestStepRefined) m_currentNode.getObject();

        m_builder.buildTestStep(String.valueOf(m_currentNode.getId()),
                testPart.getName() + m_cloneString,
                testPart.getReference().getDescription(),
                String.valueOf(m_currentNode.getParent().getId()));

        String macOfPc = null;
        Integer testBedId = parentTestPlan.getReference().getParameterIntValue(TestDesignTreeParameters.TestBedId.name());
        Integer testPlanPcId = parentTestPlan.getReference().getParameterIntValue(TestDesignTreeParameters.PcId.name());
        Integer testPlanDeviceId = parentTestPlan.getReference().getParameterIntValue(TestDesignTreeParameters.DeviceId.name());
        DutRefined testPlanDevice = null;
        TestPcRefined testPlanPc = null;
        if (testPlanPcId != null) {
            testPlanPc = TestPcFactory.newInstance().getTestPc(testPlanPcId);
        }
        if (testPlanDeviceId != null && testPlanPc != null) {
            testPlanDevice = testPlanPc.getDut(testPlanDeviceId);
        }

        String testPlanDeviceIp = parentTestPlan.getReference().getParameterStringValue(TestDesignTreeParameters.DeviceIp.name());
        String testPlanBrowserType = parentTestPlan.getReference().getParameterStringValue(TestDesignTreeParameters.BrowserType.name());
        Integer testPlanBrowserSpeed = parentTestPlan.getReference().getParameterIntValue(TestDesignTreeParameters.BrowserSpeed.name());

        if (pcId != null) {

            DeviceGroupRefined testBed = DeviceGroupFactory.newInstance().getDeviceGroup(testBedId);
            DeviceGroupDetailRefined pcItem = testBed.getDetailByPcId(pc.getId());
            macOfPc = pcItem.getMacAddress();

        } else if (testPlanPc != null) {
            DeviceGroupRefined testBed = DeviceGroupFactory.newInstance().getDeviceGroup(testBedId);
            DeviceGroupDetailRefined pcItem = testBed.getDetailByPcId(testPlanPc.getId());
            macOfPc = pcItem.getMacAddress();
        }

        if (macOfPc == null) {

            if (m_builder instanceof TestPlanBuilder) {
                ((TestPlanBuilder) m_builder).pushExceptionMessage(
                        "Mac Address of executing PC is"
                        + "TestStep. Problem Node: "
                        + getCurrentNodePath());
            }

        }
        String moduleType = TestDesign.getModuleTypeName(testPart.getReference().getModulTypeId());
        String actionType = TestDesign.getActionTypeName(testPart.getReference().getActionId());
        m_builder.setTestStepParam(String.valueOf(m_currentNode.getId()),
                macOfPc,
                AtofEnumaration.AtofModule.valueOf(
                moduleType),
                actionType,
                null,storeResultPostfix);
        if (delayTimeAfterExecute == null) {
            delayTimeAfterExecute = 0;
        }
        m_builder.setTestStepRunTime(String.valueOf(m_currentNode.getId()),
                timeout,
                delayTime,
                delayTimeAfterExecute,
                noOfRetryOnFail,
                asynchCall,
                dataArrayAppliestoCase,
                critical);

        if (successPercentage != null) {
            m_builder.setTestStepSuccessPerc(String.valueOf(m_currentNode.getId()),
                    successPercentage);
        }

        String moduleName = TestDesign.getModuleTypeName(testPart.getReference().getModulTypeId());

        LinkedHashMap<String, String> params =
                new LinkedHashMap<String, String>();

        AtofValueTranslateService service = new AtofValueTranslateService(
                TestPlanGlobalsHashMap.createInstance().getTestplanglobals(),
                TestPlanGlobalsHashMap.createInstance().getTestplanlanguages(),
                TestPlanGlobalsHashMap.createInstance().getTestplandutvalues(),
                null);
        if (moduleName.equals("WebAutomationModule")) {

            DutRefined dutInUse = null;
            if (device != null) {
                dutInUse = device;

            } else {
                dutInUse = testPlanDevice;

            }

            if (dutInUse != null) {

                params.put(AtofModuleParameterNames.WEB_AUTO_DEVICE_ID,
                        String.valueOf(dutInUse.getId()));

                params.put(AtofModuleParameterNames.WEB_AUTO_DEVICE_TESTBED_IP,
                        dutInUse.getTestBedIp());

            } else {
                if (m_builder instanceof TestPlanBuilder) {
                    ((TestPlanBuilder) m_builder).pushExceptionMessage(
                            "No device selected for"
                            + "WebAutomationModule!. Problem Node:"
                            + getCurrentNodePath());
                }
            }

            if (deviceIp != null
                    && !deviceIp.equals("")) {
                try {
                    deviceIp = service.translateValue(deviceIp);
                } catch (UnidentifiedTranslationException ex) {
                }
                params.put(AtofModuleParameterNames.WEB_AUTO_DEVICE_IP,
                        deviceIp);

            } else if (testPlanDeviceIp != null
                    && !testPlanDeviceIp.equals("")) {
                try {
                    testPlanDeviceIp = service.translateValue(testPlanDeviceIp);
                } catch (UnidentifiedTranslationException ex) {
                }
                params.put(AtofModuleParameterNames.WEB_AUTO_DEVICE_IP,
                        testPlanDeviceIp);
            } else {

                String factoryIp = getFactoryIpFromDeviceId(String.valueOf(
                        dutInUse.getId()));
                params.put(AtofModuleParameterNames.WEB_AUTO_DEVICE_IP,
                        factoryIp);
            }
            String browserType = null;
            if (curBrowserType != null) {
                browserType = curBrowserType;
            } else {
                browserType = testPlanBrowserType;
            }

            if (browserType != null) {
                params.put(AtofModuleParameterNames.WEB_AUTO_BROWSER_TYPE,
                        browserType);
            } else {
                if (m_builder instanceof TestPlanBuilder) {
                    ((TestPlanBuilder) m_builder).pushExceptionMessage(
                            "No browser selected for"
                            + "WebAutomationModule!. Problem Node:"
                            + getCurrentNodePath());
                }

            }
            String browserSpeed = null;

            if (curBrowserSpeed != null) {
                browserSpeed = curBrowserSpeed.toString();
            } else {
                browserSpeed = testPlanBrowserSpeed.toString();
            }

            if (browserSpeed != null) {
                params.put(AtofModuleParameterNames.WEB_AUTO_BROWSER_SPEED,
                        browserSpeed);
            } else {
                if (m_builder instanceof TestPlanBuilder) {
                    ((TestPlanBuilder) m_builder).pushExceptionMessage(
                            "No browser selected for"
                            + "WebAutomationModule!. Problem Node:"
                            + getCurrentNodePath());
                }
            }

        }

        if (moduleName.equals("WirelessSecurityModule") || moduleName.equals(
                "NicModule")) {
            if (nicAdapter != null) {
                String adapterName = nicAdapter.getName();
                try {
                    adapterName = service.translateValue(adapterName);
                } catch (UnidentifiedTranslationException ex) {
                }
                params.put(AtofModuleParameterNames.WSM_INTERFACE,
                        adapterName);
                params.put(AtofModuleParameterNames.WSM_WPADRIVER,
                        nicAdapter.getWpaDriver());
                params.put(AtofModuleParameterNames.NIC_INTERFACE,
                        nicAdapter.getName());
                params.put(AtofModuleParameterNames.NIC_MODTYPE,
                        nicAdapter.getAdapterType().getName());
            } else {
                if (m_builder instanceof TestPlanBuilder) {
                    ((TestPlanBuilder) m_builder).pushExceptionMessage(
                            "No Network Information Card selected"
                            + "Problem Node:"
                            + getCurrentNodePath());
                }
            }
        }


        try {
            processMapStaticVariables(params);
        } catch (RuntimeException eee) {

            if (m_builder instanceof TestPlanBuilder) {
                ((TestPlanBuilder) m_builder).pushExceptionMessage(
                        eee.getMessage()
                        + "Problem Node:"
                        + getCurrentNodePath());
            }

        }

        m_builder.setTestStepModuleParams(String.valueOf(m_currentNode.getId()),
                params);

        m_builder.setTestPartConditions(String.valueOf(m_currentNode.getId()), condList);

    }
}
